using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;

namespace Traceability.API.Services
{
    /// <summary>
    /// 基于Redis的验证码服务
    /// </summary>
    public class RedisCaptchaService
    {
        private readonly RedisService _redisService;
        private readonly CaptchaService _captchaService;
        private readonly Random _random = new Random();
        
        // Redis键前缀，用于存储验证码
        private const string CaptchaKeyPrefix = "captcha:";
        // 验证码默认过期时间（5分钟）
        private const int DefaultExpireSeconds = 300;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="redisService">Redis服务</param>
        /// <param name="captchaService">验证码服务</param>
        public RedisCaptchaService(RedisService redisService, CaptchaService captchaService)
        {
            _redisService = redisService;
            _captchaService = captchaService;
        }

        /// <summary>
        /// 生成验证码并存储到Redis
        /// </summary>
        /// <param name="length">验证码长度</param>
        /// <param name="width">图片宽度</param>
        /// <param name="height">图片高度</param>
        /// <param name="expireSeconds">过期时间（秒）</param>
        /// <returns>验证码信息（ID、图片、过期时间）</returns>
        public async Task<(string CaptchaId, byte[] ImageBytes, DateTime ExpireTime)> GenerateCaptchaAsync(
            int length = 4,
            int width = 120,
            int height = 40,
            int expireSeconds = DefaultExpireSeconds)
        {
            try
            {
                // 生成随机验证码
                string code = _captchaService.GenerateRandomCode(length);

                // 生成唯一ID
                string captchaId = $"captcha_{Guid.NewGuid():N}";

                // 计算过期时间
                DateTime expireTime = DateTime.Now.AddSeconds(expireSeconds);

                // 生成验证码图片
                byte[] imageBytes = _captchaService.GenerateCaptchaImage(code, width, height);

                // 尝试存储验证码到Redis
                string redisKey = GetRedisKey(captchaId);
                bool redisSuccess = await _redisService.StringSetAsync(redisKey, code, expireSeconds);

                if (!redisSuccess)
                {
                    throw new Exception("Redis存储失败，请检查Redis连接");
                }

                return (captchaId, imageBytes, expireTime);
            }
            catch (Exception ex)
            {
                throw new Exception($"生成验证码失败: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 验证验证码
        /// </summary>
        /// <param name="captchaId">验证码ID</param>
        /// <param name="inputCode">用户输入的验证码</param>
        /// <returns>验证结果</returns>
        public async Task<bool> ValidateCaptchaAsync(string captchaId, string inputCode)
        {
            try
            {
                if (string.IsNullOrEmpty(captchaId) || string.IsNullOrEmpty(inputCode))
                {
                    return false;
                }

                string redisKey = GetRedisKey(captchaId);

                // 从Redis获取验证码
                string storedCode = await _redisService.StringGetAsync(redisKey);

                if (string.IsNullOrEmpty(storedCode))
                {
                    return false;
                }

                // 验证成功后删除验证码（一次性使用）
                bool isValid = string.Equals(inputCode, storedCode, StringComparison.OrdinalIgnoreCase);
                if (isValid)
                {
                    await _redisService.DeleteAsync(redisKey);
                }

                return isValid;
            }
            catch (Exception)
            {
                // Redis连接失败时返回false
                return false;
            }
        }

        /// <summary>
        /// 获取Redis键名
        /// </summary>
        /// <param name="captchaId">验证码ID</param>
        /// <returns>Redis键名</returns>
        private string GetRedisKey(string captchaId)
        {
            return $"{CaptchaKeyPrefix}{captchaId}";
        }
    }
} 